

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/blog/img/favicon.png">
  <link rel="icon" href="/blog/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="Vue2数据双向绑定">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
  <title>Vue2数据双向绑定 - Mike_Blog</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/blog/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.4.0/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/blog/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"dcmaomi.gitee.io","root":"/blog/","version":"1.8.9a","typing":{"enable":true,"typeSpeed":70,"cursorChar":"|","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":"#"},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}}};
  </script>
  <script  src="/blog/js/utils.js" ></script>
  <script  src="/blog/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/blog/">&nbsp;<strong>Mike_Blog</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于我
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/links/">
                <i class="iconfont icon-link-fill"></i>
                友链
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" href="javascript:">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/blog/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="Vue2数据双向绑定">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2020-11-13 18:00" pubdate>
        2020年11月13日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      1.4k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      23
       分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Vue2数据双向绑定</h1>
            
            <div class="markdown-body">
              <h1 id="Vue2数据双向绑定"><a href="#Vue2数据双向绑定" class="headerlink" title="Vue2数据双向绑定"></a>Vue2数据双向绑定</h1><span id="more"></span>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//入口文件 index.js</span><br><span class="hljs-keyword">import</span> observe <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./observe.js&#x27;</span><br><span class="hljs-keyword">import</span> simplify <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./simplify.js&#x27;</span><br><span class="hljs-keyword">import</span> Watcher <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Watcher&#x27;</span><br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">vue</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params">&#123; el, data &#125;</span>)</span> &#123;<br>        <span class="hljs-keyword">let</span> $vm = <span class="hljs-built_in">this</span><br>        <span class="hljs-comment">// 执行data 获得数据</span><br>        $vm._data = data.call()<br><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">        对$vm.xxx数据进行拦截，所以再用vue的时候能用this 访问到</span><br><span class="hljs-comment">        其实访问的是this._data.xxx</span><br><span class="hljs-comment">        **/</span> <br>        simplify($vm)<br><br><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">        添加观测者</span><br><span class="hljs-comment">        **/</span> <br>        observe($vm._data)<br><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">        Watcher 数据监听返回 新的vale和旧的value</span><br><span class="hljs-comment">        **/</span> <br>        <span class="hljs-keyword">new</span> Watcher($vm._data, <span class="hljs-string">&#x27;x&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">val, x</span>) =&gt;</span> &#123;<br>            <span class="hljs-built_in">console</span>.log(val, x)<br>        &#125;)<br>        <span class="hljs-keyword">new</span> Watcher($vm._data, <span class="hljs-string">&#x27;g&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">val, x</span>) =&gt;</span> &#123;<br>            <span class="hljs-built_in">console</span>.log(val, x)<br>        &#125;)<br>        <span class="hljs-comment">// console.log( $vm.x)</span><br><br>    &#125;<br>&#125;<br><span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> vue(&#123;<br>    el: <span class="hljs-string">&#x27;#app&#x27;</span>,<br>    <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> &#123;<br>            a: &#123;<br>                b: &#123;<br>                    c: <span class="hljs-number">1</span><br>                &#125;<br>            &#125;,<br>            x: <span class="hljs-number">2</span>,<br>            y: <span class="hljs-number">5</span>,<br>            g: [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>]<br>        &#125;<br>    &#125;<br>&#125;)<br><br><span class="hljs-comment">// vm.g.splice(4, 1, [5, 6])</span><br><span class="hljs-comment">// vm.x = 5</span><br><span class="hljs-comment">// new Watcher(vm._data, &#x27;a.b.c&#x27;, (val, x) =&gt; &#123;</span><br><span class="hljs-comment">//     console.log(val, x)</span><br><span class="hljs-comment">// &#125;)</span><br><span class="hljs-comment">// vm.g[3]=1</span><br><span class="hljs-comment">// console.log(vm)</span><br><br></code></pre></td></tr></table></figure>
<h1 id="对数据进行初次拦截-用VM-this-xxx调用"><a href="#对数据进行初次拦截-用VM-this-xxx调用" class="headerlink" title="对数据进行初次拦截 用VM(this).xxx调用"></a>对数据进行初次拦截 用VM(this).xxx调用</h1><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">vm</span>) </span>&#123;<br>    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> vm._data) &#123;<br>        simplifyPoxy(vm, <span class="hljs-string">&#x27;_data&#x27;</span>, i)<br>        <span class="hljs-comment">// console.log(i)</span><br>    &#125;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">simplifyPoxy</span>(<span class="hljs-params">vm, targit, key</span>) </span>&#123;<br>    <span class="hljs-built_in">Object</span>.defineProperty(vm, key, &#123;<br>        <span class="hljs-function"><span class="hljs-title">get</span>(<span class="hljs-params"></span>)</span> &#123;<br>            <span class="hljs-keyword">return</span> vm[targit][key]<br>        &#125;,<br>        <span class="hljs-function"><span class="hljs-title">set</span>(<span class="hljs-params">newvalue</span>)</span> &#123;<br>            vm[targit][key] = newvalue<br>        &#125;,<br>    &#125;)<br>&#125;<br></code></pre></td></tr></table></figure>

<h1 id="获得数据先观察-数据有没有被劫持"><a href="#获得数据先观察-数据有没有被劫持" class="headerlink" title="获得数据先观察 数据有没有被劫持"></a>获得数据先观察 数据有没有被劫持</h1><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//observe.js 判断数据上有没有__ob__这个属性</span><br><span class="hljs-keyword">import</span> Observer  <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Observer.js&#x27;</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">val</span>) </span>&#123;<br>    <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> val !== <span class="hljs-string">&#x27;object&#x27;</span>) <span class="hljs-keyword">return</span><br>    <span class="hljs-keyword">let</span> ob;<br>    <span class="hljs-keyword">if</span> (val.__ob__ !== <span class="hljs-literal">undefined</span>) &#123;<br>        ob = val<br>    &#125; <span class="hljs-keyword">else</span> &#123;<br>        <span class="hljs-comment">// 没有__ob__属性就添加__ob__</span><br>        ob = <span class="hljs-keyword">new</span> Observer(val)<br>    &#125;<br>    <span class="hljs-keyword">return</span> ob<br>&#125;<br><br></code></pre></td></tr></table></figure>
<h1 id="Observerr"><a href="#Observerr" class="headerlink" title="Observerr"></a>Observerr</h1><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//observer.js</span><br><span class="hljs-keyword">import</span> &#123; dif &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./uitis&#x27;</span><br><span class="hljs-comment">//引入 观察者核心文件 ObjdefineProperty</span><br><span class="hljs-keyword">import</span> ObjdefineProperty <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./ObjdefineProperty.js&#x27;</span><br><span class="hljs-comment">//对数组定义新的方法</span><br><span class="hljs-keyword">import</span> &#123; arrarMethods &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./arr.js&#x27;</span><br><span class="hljs-keyword">import</span> observe <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./observe.js&#x27;</span><br><span class="hljs-keyword">import</span> Dep <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Dep.js&#x27;</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Observer</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params">val</span>)</span> &#123;<br>        <span class="hljs-comment">//这里引入Dep 主要是给对象(this)添加dep方法 以便成员可以调用此方法</span><br>         <span class="hljs-built_in">this</span>.dep = <span class="hljs-keyword">new</span> Dep()<br>         <span class="hljs-comment">//引入 dif方法 给对象添加新的属性</span><br>        dif(val, <span class="hljs-string">&quot;__ob__&quot;</span>, <span class="hljs-built_in">this</span>, <span class="hljs-literal">false</span>)<br><br>        <br>        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.isArray(val)) &#123;<br>            <span class="hljs-comment">//判断val是Array的话 就给添加上新的方法</span><br>            <span class="hljs-built_in">Object</span>.setPrototypeOf(val, arrarMethods)<br><br>            <span class="hljs-built_in">this</span>.isArrayObserver(val)<br>        &#125; <span class="hljs-keyword">else</span> &#123; <br>            <span class="hljs-built_in">this</span>.wark(val)<br>        &#125;<br><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">isArrayObserver</span>(<span class="hljs-params">arr</span>)</span> &#123;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>, l = arr.length; i &lt; l; i++) &#123;<br>            <span class="hljs-comment">//再次观察数据，主要针对的是val 判断val是Objietd</span><br>            observe(arr[i])<br>        &#125;<br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">wark</span>(<span class="hljs-params">val</span>)</span> &#123;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i <span class="hljs-keyword">in</span> val) &#123;<br>            ObjdefineProperty(val, i)<br>        &#125;<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h1 id="数据劫持"><a href="#数据劫持" class="headerlink" title="数据劫持"></a>数据劫持</h1><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//ObjdefineProperty.js</span><br><span class="hljs-keyword">import</span> Dep <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Dep.js&#x27;</span><br><span class="hljs-keyword">import</span> observe <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./observe.js&#x27;</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">obj, key, value</span>) </span>&#123;<br>    <span class="hljs-comment">// 引入dep 准备收集依赖</span><br>    <span class="hljs-keyword">const</span> dep = <span class="hljs-keyword">new</span> Dep()<br>    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">arguments</span>.length === <span class="hljs-number">2</span>) &#123;<br>        value = obj[key]<br>    &#125;<br>    <span class="hljs-comment">//先对 value 再次进行观察 判断是否是 objiet 是的话执行整个整体 观察者， 数据劫持循环调用</span><br>    <span class="hljs-keyword">let</span> obchalid = observe(value)<br>    <span class="hljs-built_in">Object</span>.defineProperty(obj, key, &#123;<br>        <span class="hljs-function"><span class="hljs-title">get</span>(<span class="hljs-params"></span>)</span> &#123;<br>            <span class="hljs-comment">//Dep.target 相当于是一个全局变量 判断Watcher有没有在被调用</span><br>            <span class="hljs-keyword">if</span> (Dep.target) &#123;<br>                <span class="hljs-comment">//如果在的话就收集依赖</span><br>                dep.depend()<br>                 <span class="hljs-comment">//子元素不等于undfined也要收集依赖 obchalid已经被观察过了 有dep这个实例</span><br>                <span class="hljs-keyword">if</span> (obchalid) &#123;<br>                    obchalid.dep.depend()<br>                &#125;<br>            &#125;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`你正在试图获取<span class="hljs-subst">$&#123;key&#125;</span>的值，当前值是<span class="hljs-subst">$&#123;value&#125;</span>`</span>)<br>            <span class="hljs-keyword">return</span> value<br>        &#125;,<br>        <span class="hljs-function"><span class="hljs-title">set</span>(<span class="hljs-params">newvalue</span>)</span> &#123;<br>            <span class="hljs-keyword">if</span> (value === newvalue) &#123;<br>                <span class="hljs-keyword">return</span><br>            &#125;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`你正在修改<span class="hljs-subst">$&#123;key&#125;</span>的值，修改后的值是<span class="hljs-subst">$&#123;newvalue&#125;</span>`</span>)<br>            value = newvalue<br>            <span class="hljs-comment">//对于子元素进行观测</span><br>            obchalid = observe(newvalue)<br>            <span class="hljs-comment">//通知跟新</span><br>            dep.notify()<br>        &#125;<br>    &#125;)<br>&#125;<br><br></code></pre></td></tr></table></figure>
<h1 id="数组数据劫持"><a href="#数组数据劫持" class="headerlink" title="数组数据劫持"></a>数组数据劫持</h1><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//引入 dif方法 给对象添加新的属性</span><br><span class="hljs-keyword">import</span> &#123; dif &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./uitis&#x27;</span><br><span class="hljs-comment">//重构的方法的名称</span><br><span class="hljs-keyword">const</span> methodsNeedChage = [<span class="hljs-string">&#x27;pop&#x27;</span>, <span class="hljs-string">&#x27;push&#x27;</span>, <span class="hljs-string">&#x27;shift&#x27;</span>, <span class="hljs-string">&#x27;unshift&#x27;</span>, <span class="hljs-string">&#x27;splice&#x27;</span>, <span class="hljs-string">&#x27;sort&#x27;</span>, <span class="hljs-string">&#x27;reverse&#x27;</span>]<br><span class="hljs-comment">//获取到 Array.prototype原型链上的方法</span><br><span class="hljs-keyword">const</span> arrayPortotype = <span class="hljs-built_in">Array</span>.prototype<br><span class="hljs-comment">//强制转化为对象</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> arrarMethods = <span class="hljs-built_in">Object</span>.create(arrayPortotype)<br>methodsNeedChage.forEach(<span class="hljs-function"><span class="hljs-params">methodsName</span> =&gt;</span> &#123;<br>    <span class="hljs-comment">//获取到原来arr上的方法(函数)</span><br>    <span class="hljs-keyword">const</span> a = arrayPortotype[methodsName]<br>    <span class="hljs-comment">//添加新的方法 (函数)</span><br>    dif(arrarMethods, methodsName, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>         <span class="hljs-comment">//先执行原来的方法</span><br>        <span class="hljs-keyword">const</span> result = a.apply(<span class="hljs-built_in">this</span>, <span class="hljs-built_in">arguments</span>)<br>        <span class="hljs-comment">//获取到对象的__ob__原型链</span><br>        <span class="hljs-keyword">const</span> ob = <span class="hljs-built_in">this</span>.__ob__<br>        <span class="hljs-comment">//结构形参</span><br>        <span class="hljs-keyword">const</span> args = [...arguments]<br>        <span class="hljs-keyword">let</span> incudengs = []<br>        <span class="hljs-comment">//获取到重构方法的参数(为数组添加新的成员)</span><br>        <span class="hljs-keyword">switch</span> (methodsName) &#123;<br>            <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;push&#x27;</span>:<br>            <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;unshift&#x27;</span>:<br>                incudengs = args<br>                <span class="hljs-keyword">break</span>;<br>            <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;splice&#x27;</span>:<br>                incudengs = args.slice(<span class="hljs-number">2</span>)<br>                <span class="hljs-keyword">break</span>;<br>        &#125;<br>        <span class="hljs-keyword">if</span> (incudengs) &#123;<br>            <span class="hljs-comment">//如果incudengs存在的话也被观察</span><br>            ob.isArrayObserver(incudengs)<br>            <span class="hljs-comment">// console.log(&#x27;执行了notify&#x27;)</span><br>            <span class="hljs-comment">//通知跟新</span><br>            ob.dep.notify()<br>        &#125;<br><br>        <span class="hljs-keyword">return</span> result<br>    &#125;, <span class="hljs-literal">false</span>)<br>&#125;)<br></code></pre></td></tr></table></figure>

<h1 id="收集依赖和通知跟新过程"><a href="#收集依赖和通知跟新过程" class="headerlink" title="收集依赖和通知跟新过程"></a>收集依赖和通知跟新过程</h1> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//  Dep.js</span><br> <span class="hljs-keyword">var</span> uid = <span class="hljs-number">0</span>;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dep</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-built_in">this</span>.uid = uid++;<br>        <span class="hljs-comment">// console.log(&#x27;我是Dep&#x27;)</span><br>        <span class="hljs-comment">// 数组存放的是订阅者，存放的是Watcher的实例</span><br>        <span class="hljs-built_in">this</span>.subs = []<br>    &#125;<br>    <span class="hljs-comment">// 添加订阅</span><br>    <span class="hljs-function"><span class="hljs-title">addSub</span>(<span class="hljs-params">sub</span>)</span> &#123;<br>        <span class="hljs-built_in">this</span>.subs.push(sub)<br>    &#125;<br>    <span class="hljs-comment">//添加依赖</span><br>    <span class="hljs-function"><span class="hljs-title">depend</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">if</span> (Dep.target) &#123;<br>            <span class="hljs-built_in">this</span>.addSub(Dep.target)<br>            <span class="hljs-comment">// console.log(this.subs)</span><br>        &#125;<br>       <br>    &#125;<br>    <span class="hljs-comment">//通知跟新</span><br>    <span class="hljs-function"><span class="hljs-title">notify</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-comment">//浅克隆一份this.subs</span><br>        <span class="hljs-keyword">const</span> subs = <span class="hljs-built_in">this</span>.subs.slice()<br>        <br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>, l = subs.length; i &lt; l; i++) &#123;<br>            <span class="hljs-comment">//执行跟新</span><br>            subs[i].update()<br>            <br>            <br>        &#125;<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// Watcher.js</span><br><span class="hljs-keyword">import</span> Dep <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;./Dep&quot;</span>;<br><br><span class="hljs-keyword">var</span> uid = <span class="hljs-number">0</span>;<br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Watcher</span> </span>&#123;<br>    <span class="hljs-function"><span class="hljs-title">constructor</span>(<span class="hljs-params">target, exprssiong, callback</span>)</span> &#123;<br>        <span class="hljs-built_in">this</span>.uid = uid++<br>        <span class="hljs-built_in">this</span>.target = target<br>        <span class="hljs-comment">// 获得返回来的值</span><br>        <span class="hljs-built_in">this</span>.getter = parsePath(exprssiong)<br>        <span class="hljs-built_in">this</span>.callback = callback<br>        <span class="hljs-built_in">this</span>.value = <span class="hljs-built_in">this</span>.get()<br>    &#125;<br>    <span class="hljs-comment">//进入依赖收集阶段</span><br>    <span class="hljs-function"><span class="hljs-title">get</span>(<span class="hljs-params"></span>)</span> &#123;<br>        Dep.target = <span class="hljs-built_in">this</span><br>        <span class="hljs-comment">// console.log(&#x27;创建dep.target&#x27;)</span><br>        <span class="hljs-keyword">const</span> obj = <span class="hljs-built_in">this</span>.target<br>        <span class="hljs-keyword">let</span> value;<br>        <br>        <span class="hljs-keyword">try</span> &#123;<br>            value = <span class="hljs-built_in">this</span>.getter(obj)<br>            <br>        &#125; <span class="hljs-keyword">finally</span> &#123;<br>            Dep.target = <span class="hljs-literal">null</span><br>        &#125;<br>        <span class="hljs-comment">// console.log(this.get())</span><br>        <span class="hljs-keyword">return</span> value<br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">update</span>(<span class="hljs-params"></span>)</span> &#123; <span class="hljs-built_in">this</span>.run() &#125;<br>    <span class="hljs-function"><span class="hljs-title">run</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-built_in">this</span>.gerAndInvok(<span class="hljs-built_in">this</span>.callback)<br>        <span class="hljs-comment">// console.log(1)</span><br>    &#125;<br>    <span class="hljs-function"><span class="hljs-title">gerAndInvok</span>(<span class="hljs-params">cb</span>)</span> &#123;<br>        <br>        <span class="hljs-keyword">const</span> value = <span class="hljs-built_in">this</span>.get()<br>        <span class="hljs-comment">// console.log(value !== this.value || typeof value !== &#x27;object&#x27;)</span><br>        <span class="hljs-keyword">if</span> (value !== <span class="hljs-built_in">this</span>.value || <span class="hljs-keyword">typeof</span> value !== <span class="hljs-string">&#x27;object&#x27;</span>) &#123;<br>            <span class="hljs-keyword">const</span> oldValue = <span class="hljs-built_in">this</span>.value<br>            <span class="hljs-built_in">this</span>.value = value<br>            <span class="hljs-comment">// console.log(`新值是$&#123;value&#125;,旧值是$&#123;oldValue&#125;`)</span><br>            cb.call(<span class="hljs-built_in">this</span>.target, value, oldValue)<br>        &#125;<br>    &#125;<br><br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">parsePath</span>(<span class="hljs-params">str</span>) </span>&#123;<br>    <span class="hljs-keyword">let</span> arr = str.split(<span class="hljs-string">&#x27;.&#x27;</span>)<br>    <span class="hljs-keyword">return</span> <span class="hljs-function">(<span class="hljs-params">obj</span>) =&gt;</span> &#123;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; arr.length; i++) &#123;<br>            <span class="hljs-keyword">if</span> (!obj) <span class="hljs-keyword">return</span><br>            obj = obj[arr[i]]<br>        &#125;<br><br>        <span class="hljs-keyword">return</span> obj<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h1 id="为对象定义新的方法或者值"><a href="#为对象定义新的方法或者值" class="headerlink" title="为对象定义新的方法或者值"></a>为对象定义新的方法或者值</h1> <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">//  uitis.js</span><br>  <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> dif = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">obj, key, value, enumerable</span>) </span>&#123;<br>    <span class="hljs-built_in">Object</span>.defineProperty(obj, key, &#123;<br>        <span class="hljs-comment">//value 为obj[key] 定义新的值或者方法</span><br>        value,<br>        <span class="hljs-comment">// enumerable 是否可被枚举</span><br>        enumerable,<br>        writable: <span class="hljs-literal">true</span>,<br>        configurable: <span class="hljs-literal">true</span>,<br>    &#125;)<br>&#125;<br></code></pre></td></tr></table></figure>
            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/blog/categories/Vue2/">Vue2</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/blog/tags/%E5%AD%A6%E4%B9%A0/">学习</a>
                    
                      <a class="hover-with-bg" href="/blog/tags/%E6%8E%A2%E7%B4%A2/">探索</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/blog/2021/01/13/typescript/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">typescript</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/blog/2020/11/10/Vue2%E5%92%8CVue3%E6%95%B0%E6%8D%AE%E5%8A%AB%E6%8C%81/">
                        <span class="hidden-mobile">Vue2-Vue数据双向绑定原理</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
              <!-- Comments -->
              <article class="comments" id="comments" lazyload>
                
                  
                
                

              </article>
            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
      <div class="col-lg-7 mx-auto nopadding-x-md">
        <div class="container custom mx-auto">
          <iframe frameborder="no" id="music" border="0" marginwidth="0" marginheight="0" width=330 height=86 src="//music.163.com/outchain/player?type=2&id=1397097038&auto=1&height=66"></iframe>
        </div>
      </div>
    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="#" target="_blank" rel="nofollow noopener"><span>Mike</span></a> <i class="iconfont icon-love"></i> <a href="#" target="_blank" rel="nofollow noopener"><span>Suansuan</span></a> <div class="powered-by"> <i class="fa fa-user-md"></i> </div> 
  </div>
  
  <div class="statistics">
    
    

    
      
        <!-- LeanCloud 统计PV -->
        <span id="leancloud-site-pv-container" style="display: none">
            总访问量 
            <span id="leancloud-site-pv"></span>
             次
          </span>
      
      
        <!-- LeanCloud 统计UV -->
        <span id="leancloud-site-uv-container" style="display: none">
            总访客数 
            <span id="leancloud-site-uv"></span>
             人
          </span>
      

    
  </div>


  
  <!-- 备案信息 -->
  <div class="beian">
    <span>
      <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">
        蜀ICP备2020033541号
      </a>
    </span>
    
  </div>


  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js" ></script>
<script  src="/blog/js/debouncer.js" ></script>
<script  src="/blog/js/events.js" ></script>
<script  src="/blog/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/blog/js/img-lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.0/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.0/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.6/dist/clipboard.min.js" ></script>






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>



  <script  src="/blog/js/local-search.js" ></script>
  <script>
    (function () {
      var path = "/blog/local-search.xml";
      $('#local-search-input').on('click', function() {
        searchFunc(path, 'local-search-input', 'local-search-result');
      });
      $('#modalSearch').on('shown.bs.modal', function() {
        $('#local-search-input').focus();
      });
    })()
  </script>












  

  

  

  

  

  





<!-- 主题的启动项 保持在最底部 -->
<script  src="/blog/js/boot.js" ></script>


</body>
</html>
